﻿using System;
using System.Net;
using System.IO;
using System.Collections.Generic;

namespace MxitAPI {


    /**
     * Stores the challenge data returned by the Mxit server
     */
    public class ChallengeData {

        public bool Error { get; set; }
        public string Url { get; set; }
        public string SessionId { get; set; }
        public byte[] Captcha { get; set; }
        public List<Pair<string, string>> Countries { get; set; }
        public List<Pair<string, string>> Languages { get; set; }
        public Pair<string, string> DefaultCountry { get; set; }
        public List<string> Regions { get; set; }

        public ChallengeData() {
            Countries = new List<Pair<string, string>>();
            Languages = new List<Pair<string,string>>();
            DefaultCountry = new Pair<string, string>();
            Regions = new List<string>();
        }

        public override string ToString() {
            return string.Format( "Error [{0}] | URL [{1}] | SessionId [{2}] | Captcha [{3}] | Countries [{4}] | Languages [{5}] | DefaultCountry [{6}] | Regions [{7}]", 
                Error, Url, SessionId, Captcha, Countries, Languages, DefaultCountry, Regions );
        }
    }

    /**
     * Registers the client for first time use by a user
     */
    public class GetChallengeHandler : Handler {

        public GetChallengeHandler() {
        }

        private string GetChallenge() {
            TimeSpan ts = ( DateTime.UtcNow - new DateTime( 1970, 1, 1, 0, 0, 0 ) );
            double unixTime = ts.TotalSeconds;
            HttpWebRequest myHttpWebRequest = ( HttpWebRequest ) WebRequest.Create( "http://www.mxit.com/res/?type=challenge&getcountries=true&getlanguage=true&getimage=true&ts=" + unixTime );

            // Create the proxy information object 
            //WebProxy proxy = new WebProxy( "http://146.230.94.151:8080", true );
            //proxy.Credentials = new NetworkCredential( "", "" );
            //myHttpWebRequest.Proxy = proxy;

            // Sends the HttpWebRequest and waits for the response.            
            HttpWebResponse myHttpWebResponse = ( HttpWebResponse ) myHttpWebRequest.GetResponse();
            // Gets the stream associated with the response.
            Stream receiveStream = myHttpWebResponse.GetResponseStream();

            long cLength = myHttpWebResponse.ContentLength;

            //Console.WriteLine( "\r\nResponse stream received." );
            byte[] responseBytes = new byte[cLength];
            int i = 0;
            while ( i < cLength ) {
                responseBytes[i] = ( byte ) receiveStream.ReadByte(); //readStream.Read());
                ++i;
            }

            string challengeResponse = System.Text.ASCIIEncoding.ASCII.GetString( responseBytes );

            myHttpWebResponse.Close();
            receiveStream.Close();

            return challengeResponse;
        }

        private ChallengeData ProcessChallenge( string challengeResponse ) {
            string[] challengeArr = challengeResponse.Split( ';' );

            ChallengeData challengeData = new ChallengeData();

            // Error
            if ( challengeArr[0] == "0" )
                challengeData.Error = false;
            else
                challengeData.Error = true;

            // URL
            challengeData.Url = challengeArr[1];

            // SessionId
            challengeData.SessionId = challengeArr[2];

            // Captcha
            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
            challengeData.Captcha = encoding.GetBytes( challengeArr[3] );

            // Countries
            string[] countryArr = challengeArr[4].Split( '|' );
            for ( int i = 0; i < countryArr.Length - 1; i += 2 ) 
                challengeData.Countries.Add( new Pair<string, string>( countryArr[i], countryArr[ i + 1 ] ) );

            // Languages
            string[] languageArr = challengeArr[5].Split( '|' );
            for ( int i = 0; i < languageArr.Length - 1; i += 2 )
                challengeData.Languages.Add( new Pair<string, string>( languageArr[i], languageArr[i + 1] ) );

            // Default country name
            challengeData.DefaultCountry.First = challengeArr[7];
            challengeData.DefaultCountry.First = challengeArr[6];

            // Regions
            string[] regionArr = challengeArr[8].Split( '|' );
            for ( int i = 0; i < regionArr.Length; ++i )
                challengeData.Regions.Add( languageArr[i] );
            

            // Not handled
            /*
            defaultDialingCode dialing code associated with the defaultCountryName
            defaultRegion the region of the detected IP
            defaultNPF the national dialing prefix for the defaultCountryName, e.g. 0
            defaultIPF the international dialing prefix for the defaultCountryName, e.g. 00
            cities NOT IMPLEMENTED YET
            defaultCity the city of the detected IP
            */

            return challengeData;
        }


        public override void Execute() {
            string challenge = GetChallenge();
            ChallengeData challengeData = ProcessChallenge( challenge );
            ApplicationInfo.Instance.ChallengeData = challengeData;            
        }


    }
}
